﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;
using System.Windows.Media.Animation;
using UmlControlLibrary;

namespace UmlControlLibrary
{
    /// <summary>
    /// Interaction logic for UmlInterfaceControl.xaml
    /// </summary>
    public partial class UmlClassControl : UmlDesignerElement
    {
        public static void RegisterControl()
        {
            SpecificMenu.Register(typeof(UmlProperty), GetUmlPropertyMenu());
            SpecificMenu menu = SpecificMenu.GetTypeMenu(typeof(UmlDiagramControl));
            menu.AddItem(new SpecificMenuItem("Add class", "Add", AddClass));
        }

        public UmlClassControl()
            : base()
        {
            InitializeComponent();
        }

        public override void AddSections()
        {
            base.AddSections();
            AddSection("Properties", "Properties", "PropertyListView", SpecificMenu.GetTypeMenu(typeof(UmlProperty)));
            AddSection("Methods", "Methods", "MethodListView",null);
        }

        private static SpecificMenu GetUmlPropertyMenu()
        {
            SpecificMenu.GetTypeMenu(typeof(UmlClass)).AddItem(new SpecificMenuItem("New property","Add",AddProperty));
            SpecificMenu menu = new SpecificMenu();
            menu.AddItem(new SpecificMenuItem("Delete property", "Delete", DeleteProperty));
            menu.AddItem(new SpecificMenuItem("Properties", "Properties", ShowPropertyProperties));
            return menu;
        }

        public static void AddProperty(object sender, RoutedEventArgs e)
        {
            UmlClass c = ((sender as Control).Tag as UmlContextMenu).OwnerElementDataContext as UmlClass;
            UmlProperty property = new UmlProperty("New_Property");
            UmlPropertyProperties properties = new UmlPropertyProperties();
            properties.Property = property;
            //properties.Property = (UmlProperty)property.Clone();
            Nullable<bool> result = properties.ShowDialog();
            if (result == true)
            {
               // property.CopyFrom(properties.Property);
                c.PropertyList.Add(property);
            }
        }

        public static void ShowPropertyProperties(object sender, RoutedEventArgs e)
        {
            UmlPropertyProperties properties = new UmlPropertyProperties();
            UmlProperty property = (sender as MenuItem).DataContext as UmlProperty;
//            properties.Property = (UmlProperty)property.Clone();
            properties.Property = new UmlProperty(property.ElementName);
            properties.Property.CopyFrom(property);
            Nullable<bool> result = properties.ShowDialog();
            if (result == true)
                property.CopyFrom(properties.Property);
        }

        public static void DeleteProperty(object sender, RoutedEventArgs e)
        {
            UmlClass c = ((sender as Control).Tag as UmlContextMenu).OwnerElementDataContext as UmlClass;
            UmlProperty property = (sender as MenuItem).DataContext as UmlProperty;
            if (MessageBox.Show("Remove property " + property.ElementName + " ?", "Delete item", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                c.PropertyList.Remove(property);
        }

        public static void AddClass(object sender, RoutedEventArgs e)
        {
            ContextMenuEventArgs args = ((sender as Control).Tag as UmlContextMenu).MenuEventArgs;
            UmlDiagramControl diagram = (sender as MenuItem).DataContext as UmlDiagramControl;
            UmlClass _class = new UmlClass("New_Class");
            diagram.InsertionPos = new Point(args.CursorLeft, args.CursorTop);           
            UmlModel.CurrentDiagram.AddElement(_class);
        }

        protected override Control GetControlActionsDecorator()
        {
            Control c = base.GetControlActionsDecorator();
            if (c == null)
            {
                ControlTemplate t = GetActionsDecoratorTemplate();
                RegisterActionDecorator(t, "btnTop", "Arrow_up.png", new MouseButtonEventHandler(btnGeneralize), "Generalize (or create new generalization)");
                RegisterActionDecorator(t, "btnBottom", "Arrow_up.png", new MouseButtonEventHandler(btnSpecialize), "Specialize (or create new specialization)");

                c = GetExistingActionsDecorator();
                c.Template = t;
                c.ApplyTemplate();
            }

            return c;           

        }

        private void btnGeneralize(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                LineDragThumb t1 = new LineDragThumb(this,e);
                t1.OnEndDrag += new RoutedEventHandler(btnGeneralizeEndDrag);
            }
        }

        void btnGeneralizeEndDrag(object sender, RoutedEventArgs e)
        {
            SelectableItemControl target = (e.Source as LineDragThumb).SelectedTarget;
            if (target == null)
            {
                UmlClass _class = new UmlClass((this.DataContext as UmlClass).Name+"_Base");
                UmlDiagramControl diagram = this.OwnerElement.OwnerElement as UmlDiagramControl;
                double x = this.Left;
                double y = this.Top;
                if ((x == 0) && (y == 0))
                {
                    x = this.OwnerElement.Left;
                    y = this.OwnerElement.Top;
                }
                diagram.InsertionPos = new Point(x,Math.Max(y-120,0));

                UmlModel.CurrentDiagram.AddElement(_class);
                
                target = UmlModel.CurrentDiagram.DiagramControls[_class];
            }
            if ((target != null) && ((target.DataContext is UmlClass) || (target.DataContext is UmlInterface)))
                (this.DataContext as UmlClass).Parent += "," + (target.DataContext as DiagramElement).Name;
        }

        private void btnSpecialize(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                LineDragThumb t1 = new LineDragThumb(this, e);
                t1.OnEndDrag += new RoutedEventHandler(btnSpecializeEndDrag);
            }
        }

        void btnSpecializeEndDrag(object sender, RoutedEventArgs e)
        {
            SelectableItemControl target = (e.Source as LineDragThumb).SelectedTarget;
            if (target == null)
            {
                UmlClass _class = new UmlClass((this.DataContext as UmlClass).Name + "_Derived");
                UmlDiagramControl diagram = this.OwnerElement.OwnerElement as UmlDiagramControl;
                double x = this.Left;
                double y = this.Bottom;
                if ((x == 0) && (y == 0))
                {
                    x = this.OwnerElement.Left;
                    y = this.OwnerElement.Bottom;
                }
                diagram.InsertionPos = new Point(x, y + 40);

                UmlModel.CurrentDiagram.AddElement(_class);

                target = UmlModel.CurrentDiagram.DiagramControls[_class];
            }
            if ((target != null) && ((target.DataContext is UmlClass) || (target.DataContext is UmlInterface)))
                (target.DataContext as DiagramElement).Parent += "," + (this.DataContext as UmlClass).Name;
        }
    
    }


}
